package Technical;

import domain.MCState;
import java.sql.*;

/**
 * @author Anders
 */
public class DatabaseHandler
{

    private static DatabaseHandler dh;
    private Connection conn;

    private DatabaseHandler()
    {
        try {

            Class.forName("org.sqlite.JDBC");
            conn = DriverManager.getConnection("jdbc:sqlite:db.db");


        } catch (ClassNotFoundException | SQLException ex) {
            System.out.println("Couldn't connect to the database!");
        }
    }

    public static DatabaseHandler getInstance()
    {
        if (dh == null) {
            dh = new DatabaseHandler();
        }
        return dh;
    }

    public void SaveState(MCState state)
    {
        String byteString = convertByteToString(state.getBoard());

        if (!checkState(state)) {
            try {
                Statement st = conn.createStatement();
                st.executeUpdate("INSERT INTO states VALUES ('" + byteString + "', " + state.getPlayer1Score() + ", " + state.getPlayer2Score() + ");");

            } catch (SQLException ex) {
                System.out.println("Couldn't perform a save state!");
            }
        } else {
            updateState(state);
        }
    }

    // returns true if exists, false if not.
    public boolean checkState(MCState state)
    {
        try {
            String byteString = convertByteToString(state.getBoard());

            Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery("SELECT Board FROM states WHERE Board = '" + byteString + "';");

            if (rs.next()) {
                return true;

            }

        } catch (SQLException ex) {
            System.out.println("Couldn't perform a check state!");
        }
        return false;
    }

    public void updateState(MCState state)
    {
        try {
            String byteString = convertByteToString(state.getBoard());
            Statement st = conn.createStatement();
            st.executeUpdate("UPDATE states SET Player1Score = '" + state.getPlayer1Score() + "', Player2Score = '" + state.getPlayer2Score() + "' WHERE Board = '" + byteString + "';");

        } catch (SQLException ex) {
            System.out.println("Couldn't perform a update state! " + ex.getMessage());
        }
    }

    public MCState lookup(MCState state)
    {
        String byteString = convertByteToString(state.getBoard());

        try {
            Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery("SELECT * FROM states WHERE Board = '" + byteString + "';");

            if (rs.next()) {
                String p1 = rs.getString(2);
                String p2 = rs.getString(3);

                double p1d = Double.parseDouble(p1);
                double p2d = Double.parseDouble(p2);

                state.setPlayer1score(p1d);
                state.setPlayer2score(p2d);
                
                return state;
            }
        } catch (SQLException ex) {
            System.out.println("Couldn't perform a lookup! " + ex.getSQLState());
            ex.printStackTrace();
        }
        return null;
    }

    public void tunaktuankDB()
    {
        try {
            Statement st = conn.createStatement();
            st.execute("DELETE FROM states");
        } catch (Exception e) {
            System.out.println("Couldn't perform a truncate!");
        }
    }

    public String convertByteToString(byte[] x)
    {
        String byteString = "";
        for (int i = 0; i < x.length; i++) {
            byteString += x[i];
        }
        return byteString;
    }
}